import fs from 'fs-extra';
import path from 'path';
import { Tag, TagsData, CreateTagRequest, UpdateTagRequest } from '../types/tag';
import { ApiResponse, PaginationQuery } from '../types/api';
import { PATHS } from '../config';

/**
 * 标签服务类 - 负责标签数据的文件操作
 */
export class TagService {
  private tagsFilePath: string;
  private backupPath: string;

  constructor() {
    this.tagsFilePath = path.join(PATHS.DATA, 'tags.json');
    this.backupPath = PATHS.BACKUP;
    this.initializeDataDirectory();
  }

  /**
   * 初始化数据目录
   */
  private async initializeDataDirectory(): Promise<void> {
    try {
      // 确保数据目录存在
      await fs.ensureDir(PATHS.DATA);
      await fs.ensureDir(this.backupPath);
      
      // 如果tags.json不存在，创建空文件
      if (!(await fs.pathExists(this.tagsFilePath))) {
        const initialData: TagsData = {
          tags: [],
          metadata: {
            version: '1.0.0',
            lastUpdated: new Date().toISOString(),
            totalCount: 0
          }
        };
        await fs.writeJson(this.tagsFilePath, initialData, { spaces: 2 });
        console.log('Created initial tags.json file');
      }
    } catch (error) {
      console.error('Failed to initialize tags data directory:', error);
      throw error;
    }
  }

  /**
   * 读取所有标签数据
   */
  async getAllTags(): Promise<Tag[]>;
  async getAllTags(options: {
    page?: number;
    limit?: number;
    search?: string;
    sortBy?: string;
    sortOrder?: string;
  }): Promise<{
    tags: Tag[];
    page: number;
    limit: number;
    total: number;
    totalPages: number;
  }>;
  async getAllTags(options?: {
    page?: number;
    limit?: number;
    search?: string;
    sortBy?: string;
    sortOrder?: string;
  }): Promise<Tag[] | {
    tags: Tag[];
    page: number;
    limit: number;
    total: number;
    totalPages: number;
  }> {
    try {
      const data: TagsData = await fs.readJson(this.tagsFilePath);
      let tags = Array.isArray(data.tags) ? data.tags : [];
      
      // 如果没有传入选项，返回简单的标签数组
      if (!options) {
        return tags;
      }
      
      // 应用搜索过滤
      if (options.search) {
        const searchLower = options.search.toLowerCase();
        tags = tags.filter(tag => 
          tag.name.toLowerCase().includes(searchLower) ||
          (tag.description || '').toLowerCase().includes(searchLower)
        );
      }
      
      // 排序
      const sortBy = options.sortBy || 'createdAt';
      const sortOrder = options.sortOrder || 'desc';
      
      tags.sort((a, b) => {
        let aValue: any = a[sortBy as keyof Tag];
        let bValue: any = b[sortBy as keyof Tag];
        
        if (sortBy === 'createdAt' || sortBy === 'updatedAt') {
          aValue = new Date(aValue).getTime();
          bValue = new Date(bValue).getTime();
        }
        
        if (sortOrder === 'asc') {
          return aValue > bValue ? 1 : -1;
        } else {
          return aValue < bValue ? 1 : -1;
        }
      });
      
      // 分页
      const page = options.page || 1;
      const limit = options.limit || 10;
      const startIndex = (page - 1) * limit;
      const endIndex = startIndex + limit;
      
      const paginatedTags = tags.slice(startIndex, endIndex);
      const totalPages = Math.ceil(tags.length / limit);
      
      return {
        tags: paginatedTags,
        page,
        limit,
        total: tags.length,
        totalPages
      };
    } catch (error) {
      console.error('Failed to read tags file:', error);
      return options ? {
        tags: [],
        page: options.page || 1,
        limit: options.limit || 10,
        total: 0,
        totalPages: 0
      } : [];
    }
  }

  /**
   * 根据ID获取标签
   */
  async getTagById(id: string): Promise<Tag | null> {
    try {
      const tags = await this.getAllTags();
      return tags.find(tag => tag.id === id) || null;
    } catch (error) {
      console.error('Failed to get tag by ID:', error);
      return null;
    }
  }

  /**
   * 根据名称获取标签
   */
  async getTagByName(name: string): Promise<Tag | null> {
    try {
      const tags = await this.getAllTags();
      return tags.find(tag => tag.name === name) || null;
    } catch (error) {
      console.error('Failed to get tag by name:', error);
      return null;
    }
  }

  /**
   * 分页查询标签
   */
  async getTagsPaginated(query: PaginationQuery): Promise<ApiResponse<Tag[]>> {
    try {
      let tags = await this.getAllTags();
      
      // 应用搜索过滤
      if (query.search) {
        const searchLower = query.search.toLowerCase();
        tags = tags.filter(tag => 
          tag.name.toLowerCase().includes(searchLower) ||
          (tag.description || '').toLowerCase().includes(searchLower)
        );
      }
      
      // 排序（按创建时间倒序）
      tags.sort((a, b) => new Date(b.createdAt).getTime() - new Date(a.createdAt).getTime());
      
      // 分页
      const page = query.page || 1;
      const limit = query.limit || 10;
      const startIndex = (page - 1) * limit;
      const endIndex = startIndex + limit;
      
      const paginatedTags = tags.slice(startIndex, endIndex);
      
      return {
        success: true,
        data: paginatedTags,
        total: tags.length,
        page,
        limit
      };
    } catch (error) {
      console.error('Failed to get paginated tags:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }

  /**
   * 创建新标签
   */
  async createTag(input: CreateTagRequest): Promise<ApiResponse<Tag>> {
    try {
      const tags = await this.getAllTags();
      
      // 检查名称是否已存在
      const existingTag = tags.find(tag => tag.name === input.name);
      if (existingTag) {
        return {
          success: false,
          error: 'Tag name already exists'
        };
      }
      
      // 生成唯一ID
      const id = this.generateId();
      const now = new Date().toISOString();
      
      const newTag: Tag = {
        id,
        name: input.name,
        color: input.color || '#00ff88',
        description: input.description || '',
        createdAt: now,
        updatedAt: now
      };
      
      tags.push(newTag);
      
      // 创建备份
      await this.createBackup();
      
      // 保存到文件
      const data: TagsData = {
        tags,
        metadata: {
          version: '1.0.0',
          lastUpdated: now,
          totalCount: tags.length
        }
      };
      await fs.writeJson(this.tagsFilePath, data, { spaces: 2 });
      
      return {
        success: true,
        data: newTag
      };
    } catch (error) {
      console.error('Failed to create tag:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }

  /**
   * 更新标签
   */
  async updateTag(id: string, input: UpdateTagRequest): Promise<ApiResponse<Tag>> {
    try {
      const tags = await this.getAllTags();
      const tagIndex = tags.findIndex(tag => tag.id === id);
      
      if (tagIndex === -1) {
        return {
          success: false,
          error: 'Tag not found'
        };
      }
      
      // 检查名称是否与其他标签冲突
      if (input.name) {
        const existingTag = tags.find(tag => tag.name === input.name && tag.id !== id);
        if (existingTag) {
          return {
            success: false,
            error: 'Tag name already exists'
          };
        }
      }
      
      // 创建备份
      await this.createBackup();
      
      // 更新标签
      tags[tagIndex] = {
        ...tags[tagIndex],
        ...input,
        updatedAt: new Date().toISOString()
      };
      
      // 保存到文件
      const data: TagsData = {
        tags,
        metadata: {
          version: '1.0.0',
          lastUpdated: new Date().toISOString(),
          totalCount: tags.length
        }
      };
      await fs.writeJson(this.tagsFilePath, data, { spaces: 2 });
      
      return {
        success: true,
        data: tags[tagIndex]
      };
    } catch (error) {
      console.error('Failed to update tag:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }

  /**
   * 删除标签
   */
  async deleteTag(id: string): Promise<ApiResponse<Tag>> {
    try {
      const tags = await this.getAllTags();
      const tagIndex = tags.findIndex(tag => tag.id === id);
      
      if (tagIndex === -1) {
        return {
          success: false,
          error: 'Tag not found'
        };
      }
      
      // 创建备份
      await this.createBackup();
      
      // 删除标签
      const deletedTag = tags.splice(tagIndex, 1)[0];
      
      // 保存到文件
      const data: TagsData = {
        tags,
        metadata: {
          version: '1.0.0',
          lastUpdated: new Date().toISOString(),
          totalCount: tags.length
        }
      };
      await fs.writeJson(this.tagsFilePath, data, { spaces: 2 });
      
      return {
        success: true,
        data: deletedTag
      };
    } catch (error) {
      console.error('Failed to delete tag:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }

  /**
   * 创建数据备份
   */
  private async createBackup(): Promise<void> {
    try {
      const timestamp = new Date().toISOString().replace(/[:.]/g, '-');
      const backupFileName = `tags-backup-${timestamp}.json`;
      const backupFilePath = path.join(this.backupPath, backupFileName);
      
      if (await fs.pathExists(this.tagsFilePath)) {
        await fs.copy(this.tagsFilePath, backupFilePath);
        
        // 清理旧备份（保留最近10个）
        await this.cleanupOldBackups();
      }
    } catch (error) {
      console.error('Failed to create tags backup:', error);
    }
  }

  /**
   * 清理旧备份文件
   */
  private async cleanupOldBackups(): Promise<void> {
    try {
      const backupFiles = await fs.readdir(this.backupPath);
      const tagBackups = backupFiles
        .filter((file: string) => file.startsWith('tags-backup-') && file.endsWith('.json'))
        .sort()
        .reverse(); // 最新的在前
      
      // 保留最近10个备份
      const filesToDelete = tagBackups.slice(10);
      
      for (const file of filesToDelete) {
        await fs.remove(path.join(this.backupPath, file));
      }
    } catch (error) {
      console.error('Failed to cleanup old tag backups:', error);
    }
  }

  /**
   * 生成唯一ID
   */
  private generateId(): string {
    const { v4: uuidv4 } = require('uuid');
    return uuidv4();
  }

  /**
   * 批量删除标签
   */
  async batchDeleteTags(ids: string[]): Promise<number> {
    try {
      const tags = await this.getAllTags();
      let deletedCount = 0;
      
      // 创建备份
      await this.createBackup();
      
      // 过滤掉要删除的标签
      const remainingTags = tags.filter(tag => {
        if (ids.includes(tag.id)) {
          deletedCount++;
          return false;
        }
        return true;
      });
      
      // 保存到文件
      const data: TagsData = {
        tags: remainingTags,
        metadata: {
          version: '1.0.0',
          lastUpdated: new Date().toISOString(),
          totalCount: remainingTags.length
        }
      };
      await fs.writeJson(this.tagsFilePath, data, { spaces: 2 });
      
      return deletedCount;
    } catch (error) {
      console.error('Failed to batch delete tags:', error);
      throw error;
    }
  }

  /**
   * 获取标签统计信息
   */
  async getTagStats(): Promise<{ totalCount: number; lastUpdated: string }> {
    try {
      const tags = await this.getAllTags();
      return {
        totalCount: tags.length,
        lastUpdated: new Date().toISOString()
      };
    } catch (error) {
      console.error('Failed to get tag stats:', error);
      throw error;
    }
  }

  /**
   * 导出标签数据
   */
  async exportTags(): Promise<Tag[]> {
    return await this.getAllTags();
  }

  /**
   * 导入标签数据
   */
  async importTags(tags: Tag[]): Promise<ApiResponse<{ count: number }>> {
    try {
      // 验证数据格式
      if (!Array.isArray(tags)) {
        return {
          success: false,
          error: 'Invalid data format: expected array'
        };
      }
      
      // 创建备份
      await this.createBackup();
      
      // 保存导入的数据
      const data: TagsData = {
        tags,
        metadata: {
          version: '1.0.0',
          lastUpdated: new Date().toISOString(),
          totalCount: tags.length
        }
      };
      await fs.writeJson(this.tagsFilePath, data, { spaces: 2 });
      
      return {
        success: true,
        data: { count: tags.length }
      };
    } catch (error) {
      console.error('Failed to import tags:', error);
      return {
        success: false,
        error: error instanceof Error ? error.message : 'Unknown error'
      };
    }
  }
}

// 导出单例实例
export const tagService = new TagService();